#!/usr/bin/env python
# -*- coding: utf-8 -*-


#import base64

#######################################################################

MIN_PACKET_ID = 1
MAX_PACKET_ID = 65535
packet_id_current = MAX_PACKET_ID

PP_ACTION_REQUEST  = 'REQUEST'
PP_ACTION_RESPONSE = 'RESPONSE'

#######################################################################


class   Packet(object)  :
    def __init__(self) :
        self.action = None
        self.service = None
        self.body = None
        self.packid = 0
        self.respid = 0
        # __init__()

    def __str__(self) :
        s = "action:%s service:%s packid:%d" % (self.action, self.service, self.packid)
        if self.respid > 0 :
            s += " respid:%d" % self.respid
        s += " body:'%s'" % self.body
        return s
        # __str__()

    def isComplete(self) :
        if not self.action or not self.service or not self.body :
            return  False
        return  True

    def setRequest(self) :
        if PP_ACTION_REQUEST == self.action : return
        self.action = PP_ACTION_REQUEST
    def setResponse(self) :
        if PP_ACTION_RESPONSE == self.action : return
        self.action = PP_ACTION_RESPONSE

    def isRequest(self) :
        if PP_ACTION_REQUEST == self.action : return True
        return  False
    def isResponse(self) :
        if PP_ACTION_RESPONSE == self.action : return True
        return  False
    # class Packet

#######################################################################

def depack(record) :
    '''decode packet record string into Packet struct'''
    field_separator = '\t'
    kv_separator = ':'
    packet = Packet()
    fields = record.split(field_separator)
    for f in fields :
        (key, value) = f.split(kv_separator, 1)
        if not value : continue
        if 'action' == key :
            packet.action = value
        elif 'service' == key :
            packet.service = value
        elif 'packid' == key :
            packet.packid = int(value)
        elif 'respid' == key :
            packet.respid = int(value)
        elif 'body' == key :
            packet.body = value
            #packet.body = base64.b64decode(value)

    if not packet.isComplete() : return None
    return  packet
    # depack()

def enpack(packet) :
    '''encode Packet struct into packet record string'''
    packid = packet.packid
    if not packid :  packid = nextPacketID()
    fields = []
    fields.append('action:%s' % packet.action)
    fields.append('service:%s' % packet.service)
    fields.append('packid:%d' % packid)
    if packet.respid > 0 :
        fields.append('respid:%d' % packet.respid)
    fields.append(':'.join(['body', packet.body]))
    #fields.append(':'.join(['body', base64.b64encode(packet.body)]))
    record = '\t'.join(fields)
    return  (record, packid)
    # enpack

def enpack_bak(packet) :
    '''encode Packet struct into packet record string'''
    packid = packet.packid
    if not packid :  packid = nextPacketID()
    record = "action:%s\tservice:%s\tpackid:%d" % (packet.action, packet.service, packid)
    if packet.respid > 0 :
        record += "\trespid:%d" % packet.respid
    record += "\tbody:%s" % base64.b64encode(packet.body)
    return  (record, packid)
    # enpack

def nextPacketID() :
    global  packet_id_current
    if packet_id_current == MAX_PACKET_ID :
        packet_id_current = MIN_PACKET_ID
    else :
        packet_id_current += 1
    return  packet_id_current
    # packetid()

#######################################################################


__all__ = [ 'Packet', 'enpack', 'depack' ]


